



from mscf.fc3.project.volfitter.marketdata.optionmarketdata import OptionMarketData, OptionPriceChain, OptionMktPrice


from optionmarketdata import OptionMarketData, OptionMktPrice, OptionPriceChain
import pprint
import urllib2,sys
from bs4 import BeautifulSoup

import datetime
import dateutil.relativedelta as relativedelta
import dateutil.rrule as rrule

STRIKE_BY_SPOT_LOWER_BOUND = 0.6
STRIKE_BY_SPOT_UPPER_BOUND = 1.2


class MarketDataFetcher:

    def __init__(self):
        self.x=5


    @staticmethod
    def fetchData(ticker,testExpDate,refSpot):
        callPriceArray = []
        putPriceArray = []
        html = urllib2.urlopen('http://finance.yahoo.com/q/op?s='+str(ticker)+'&m='+testExpDate).read()
        soup=BeautifulSoup(html,'html5lib')
        t = soup.findAll('table')
        optionStrike = None
        optionBid = None
        optionAsk = None
        for table in t:
            mode=None
            optionType=None
            rows = table.findAll('tr')
            for tr in rows:
                colCount = 0
                newLine = True
                cols = tr.findAll('td')
                for td in cols:
                    try:
                        tdVal = td.find(text=True)
                        if((tdVal != None) and (str(tdVal) == "Strike")):
                            mode=1
                            colCount = 0
                            if(optionType == None):
                                optionType = "Call"
                            elif(optionType == "Call"):
                                optionType = "Put"

                        if(tdVal != None and str(tdVal) == "None"):
                            mode=0
                            colCount = 0
                        if(tdVal == None):
                            mode=0
                            colCount = 0
                        if(mode==1 and str(tdVal) != "Strike"):
                            colCount += 1
                            if(newLine):

                                newLine = False

                            if(colCount % 8 == 1 and str(tdVal) != "None"):
                                try:
                                    flowVal = float(tdVal)
                                    #if(flowVal > optionStrike)
                                    optionStrike=flowVal
                                except ValueError:
                                    pass

                            if(colCount % 8 == 5):
                                try:
                                    optionBid=float(tdVal)
                                except ValueError:
                                    pass

                            if(colCount % 8 == 6):
                                try:
                                    optionAsk=float(tdVal)
                                except ValueError:
                                    pass


                            if(colCount % 8 == 0 and colCount !=0):
                                if(optionStrike >= refSpot * STRIKE_BY_SPOT_LOWER_BOUND and optionStrike <= refSpot * STRIKE_BY_SPOT_UPPER_BOUND):
                                    if(optionType=="Call"):
                                        callPrice = OptionMktPrice(optionStrike,optionBid,optionAsk)
                                        callPriceArray.append(callPrice)
                                    elif(optionType=="Put"):
                                        putPrice = OptionMktPrice(optionStrike,optionBid,optionAsk)
                                        putPriceArray.append(putPrice)
                                optionStrike = None
                                optionBid = 0.0
                                optionAsk = 0.0
                                newLine = True
                    except UnicodeEncodeError:
                        return (callPriceArray, putPriceArray)
        return (callPriceArray, putPriceArray)

    @staticmethod
    def fetchMarketData(ticker, refSpot):


        now = datetime.date.today()

        optionPriceChainMap = dict()
        for i in range(0,18):
            dateVal = now + relativedelta.relativedelta( months = +i )

            if dateVal.year == now.year or  dateVal.month == 1 or dateVal.month % 3 == 0:

                #pick up the third friday
                expDateTime= rrule.rrule(rrule.MONTHLY, byweekday=(relativedelta.FR(3)), dtstart=dateVal)[0]
                expDate = datetime.date(expDateTime.year, expDateTime.month, expDateTime.day)

                dateStr = expDate.strftime("%Y-%m")

                expOptionPriceData = MarketDataFetcher.fetchData(ticker,dateStr, refSpot)
                optionPriceChain = OptionPriceChain(expDate, expOptionPriceData[0], expOptionPriceData[1])
                if(len(optionPriceChain.callPutPairMap.keys()) != 0):
                    optionPriceChainMap[expDate] = optionPriceChain


                #   nextMonthDate = testExpDate + relativedelta( months = 1 )
                #   optionPriceChainMap[nextMonthDate] = optionPriceChain

        optionMarketData = OptionMarketData(optionPriceChainMap, datetime.date.today(), refSpot)

        return optionMarketData





